package bll

import (
	"context"
	"encoding/json"
	"github.com/prometheus/common/log"
	"golang.org/x/sync/errgroup"
	"gorm.io/gorm"
	"manager/auth"
	"manager/client/grpc"
	"manager/errors"
	"manager/model"
	"manager/model/entity"
	"manager/model/po"
	"manager/store/postgres"
	"proto/dto"
)

// GetBikeLocation 车辆位置
func (a *ebike) GetBikeLocation(sn string) (lo *po.Location) {
	lo = &po.Location{}
	// 进行计算车辆当前位置和设防的位置，触发被盗告警，距离超过100米就告警且车辆在线
	shadowRsp, err := grpc.SCmd.GetShadowAttributes(context.Background(), &dto.GetShadowAttributesRequest{
		DeviceName: sn,
	})
	if err != nil {
		return
	}

	type shadowAttribute struct {
		Location string `json:"location"`
	}
	// 解析影子
	var attribute shadowAttribute
	if shadowRsp.Attribute == "" {
		return
	}

	// 解析
	err = json.Unmarshal([]byte(shadowRsp.Attribute), &attribute)
	if err != nil {
		return
	}

	// 解析
	err = json.Unmarshal([]byte(attribute.Location), &lo)
	if err != nil {
		return
	}
	return
}

// BikeInfo 车辆详情
func (a *ebike) BikeInfo(ctx context.Context, bikeId int64) (info *model.BikeInfo, err error) {
	var (
		bikeInfo   *entity.Ebike
		controlEty *entity.Control
		bikeType   *entity.EbikeType
		eg         *errgroup.Group
	)

	userId, _ := auth.ContextUserID(ctx)
	eg, ctx = errgroup.WithContext(ctx)

	// 车辆信息
	bikeInfo, err = a.iEbike.Find(ctx, bikeId)
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, errors.EbikeQueryFailed.Error()
	}

	if err != nil {
		log.Error(err)
		return nil, err
	}

	// 门店信息
	storeName := ""
	eg.Go(func() error {
		// 门店
		storeInfo, _ := postgres.Store.Find(ctx, bikeInfo.StoreID)
		if storeInfo != nil {
			storeName = storeInfo.Name
		}
		return nil
	})

	// 中控
	eg.Go(func() error {
		// 中控
		controlEty, _ = a.iControl.Find(ctx, &model.ControlInfoRequest{
			Id: bikeInfo.ControlId,
		})
		return nil
	})

	// 电池
	batteryInfo := &entity.Battery{}
	batterTypeInfo := &entity.BatteryType{}
	eg.Go(func() error {
		// 车型
		batteryInfo, _ = postgres.Battery.Find(ctx, &model.BatteryInfoRequest{
			Id: bikeInfo.BatteryId,
		})

		if batteryInfo != nil && batteryInfo.Id > 0 {
			batterTypeInfo, _ = postgres.BatteryType.Find(ctx, &model.BatteryTypeInfoRequest{
				Id: batteryInfo.BatteryType,
			})
		}
		return nil
	})

	eg.Go(func() error {
		// 车型
		bikeType, err = a.iEbikeType.Find(bikeInfo.TypeID)
		return nil
	})

	// 自定义车辆信息
	var userbikeSettingEty *entity.UserBikeSetting
	eg.Go(func() error {
		userbikeSettingEty, _ = a.iUserBikeSetting.Find(ctx, &model.UserBikeSettingInfoRequest{
			UserId:  &userId,
			EbikeId: &bikeInfo.ID,
		})
		return nil
	})

	// 车辆位置
	var location *po.Location
	eg.Go(func() error {
		location = a.GetBikeLocation(bikeInfo.SNCode)
		return nil
	})

	err = eg.Wait()

	if err != nil {
		log.Error(err)
		return nil, errors.EbikeQueryFailed.Error()
	}

	// 车辆名称
	bikeName := bikeInfo.Name
	if userbikeSettingEty.EbikeName != "" {
		bikeName = userbikeSettingEty.EbikeName
	}
	// 车辆图片
	bikeImage := EbikeType.GetBikeImage(bikeInfo.TypeID, bikeInfo.Color)
	/*	if userbikeSettingEty.EbikeImage != "" {
		bikeImage = userbikeSettingEty.EbikeImage
	}*/

	// 售卖日期和三包 造假数据
	info = &model.BikeInfo{
		ID:               bikeInfo.ID,
		TypeID:           bikeInfo.TypeID,
		Name:             bikeName,
		Photo:            bikeImage,
		Color:            bikeInfo.Color,
		Status:           bikeInfo.Status,
		FrameCode:        bikeInfo.FrameCode,
		EngineCode:       bikeInfo.EngineCode,
		IsBind:           bikeInfo.IsBind,
		Stock:            bikeInfo.Stock,
		StoreID:          bikeInfo.StoreID,
		ControlId:        bikeInfo.ControlId,
		BatteryId:        bikeInfo.BatteryId,
		BindUsers:        bikeInfo.BindUsers,
		CreatedAt:        bikeInfo.CreatedAt,
		UpdatedAt:        bikeInfo.UpdatedAt,
		SNCode:           bikeInfo.SNCode,
		SocketType:       bikeType.SocketType,
		TypeName:         bikeType.Name,
		Mac:              controlEty.Mac,
		Imei:             controlEty.Imei,
		Iccid:            controlEty.Iccid,
		Imsi:             controlEty.Imsi,
		FirmwareVersion:  controlEty.FirmwareVersion,
		BatteryCode:      batteryInfo.BatteryCode,
		FirmwaresVersion: batteryInfo.FirmwaresVersion,
		BatteryName:      batterTypeInfo.Name,
		Version:          batterTypeInfo.Version,
		Voltage:          batterTypeInfo.Voltage,
		Type:             batterTypeInfo.Type,
		Supplier:         batterTypeInfo.Supplier,
		Capacity:         batterTypeInfo.Capacity,

		StoreName:          storeName,
		BuyTime:            bikeInfo.SaleTime,
		ActivationTime:     bikeInfo.ActivationTime,
		WarrantyPeriodTime: bikeInfo.SaleTime + 365*24*3600,

		Location: *location,
	}

	return
}

func (a *ebike) AppInfo(ctx context.Context, in *model.EbikeBaseRequest) (*model.AppEbikeInfoResponse, error) {
	var (
		err         error
		ety         *entity.Ebike
		out         *model.AppEbikeInfoResponse
		controlEty  *entity.Control
		typeEty     *entity.EbikeType
		userbikeEty *entity.UserEbike
		eg          *errgroup.Group
	)

	userId, _ := auth.ContextUserID(ctx)
	eg, ctx = errgroup.WithContext(ctx)

	ety, err = a.iEbike.Find(ctx, in.ID)
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, errors.EbikeQueryFailed.Error()
	}
	if err != nil {
		log.Error(err)
		return nil, err
	}

	// 中控
	eg.Go(func() error {
		// 中控
		controlEty, _ = a.iControl.Find(ctx, &model.ControlInfoRequest{
			Id: ety.ControlId,
		})
		return nil
	})

	// 车型
	eg.Go(func() error {
		// 车型
		typeEty, err = a.iEbikeType.Find(ety.TypeID)
		return err
	})

	eg.Go(func() error {
		// 用户车辆信息
		userbikeEty, err = a.iUserEbike.FindByParameter(ctx, &model.UserEbikeRequest{EbikeID: &ety.ID})
		return nil
	})

	// 自定义车辆信息
	var userbikeSettingEty *entity.UserBikeSetting
	eg.Go(func() error {
		userbikeSettingEty, _ = a.iUserBikeSetting.Find(ctx, &model.UserBikeSettingInfoRequest{
			UserId:  &userId,
			EbikeId: &ety.ID,
		})
		return nil
	})

	err = eg.Wait()

	if err != nil {
		log.Error(err)
		return nil, err
	}

	// 车辆名称
	bikeName := ety.Name
	if userbikeSettingEty.EbikeName != "" {
		bikeName = userbikeSettingEty.EbikeName
	}

	// 车辆图片
	bikeImage := userbikeEty.Photo
	if userbikeSettingEty.EbikeImage != "" {
		bikeImage = userbikeSettingEty.EbikeImage
	}

	// 售卖日期和三包 造假数据
	out = &model.AppEbikeInfoResponse{
		ID:              ety.ID,
		TypeID:          ety.TypeID,
		TypeName:        bikeName,
		Name:            ety.Name,
		Image:           bikeImage,
		SocketType:      typeEty.SocketType,
		Status:          ety.Status,
		FrameCode:       ety.FrameCode,
		EngineCode:      ety.EngineCode,
		Color:           ety.Color,
		IsBind:          ety.IsBind,
		Stock:           ety.Stock,
		FirmwareID:      0, //固件ID
		StoreID:         ety.StoreID,
		CreatedAt:       ety.CreatedAt,
		UpdatedAt:       ety.CreatedAt,
		BindUsers:       ety.BindUsers,
		SNCode:          ety.SNCode,
		Mac:             controlEty.Mac,
		Imei:            controlEty.Imei,
		Iccid:           controlEty.Iccid,
		Imsi:            controlEty.Imsi,
		FirmwareVersion: controlEty.FirmwareVersion,
		IsManager:       userbikeEty.IsManager,
		// 假数据
		// TODO 改掉
		StoreName:          "浙江省杭州市余杭区电摩智电动旗舰店",
		BuyTime:            1681542465,
		ActivationTime:     1681542465,
		WarrantyPeriodTime: 1776236820,
	}

	return out, err

}
